// currencyConverter.ts

// 缓存条目接口
interface CacheEntry {
  rate: number;
  timestamp: number;
}

// 缓存信息接口
interface CacheInfoEntry {
  key: string;
  rate: number;
  age: string;
  expiresIn: string;
}

// 缓存信息接口
interface CacheInfo {
  size: number;
  entries: CacheInfoEntry[];
}

// API提供商类型
type ApiProvider = 'frankfurter' | 'exchangerate';

// API响应接口
interface FrankfurterResponse {
  rates: Record<string, number>;
  base: string;
  date: string;
}

interface ExchangeRateResponse {
  rates: Record<string, number>;
  base: string;
  date: string;
}

class CurrencyConverter {
  private apiProvider: ApiProvider;
  private cache: Map<string, CacheEntry>;
  private readonly CACHE_DURATION: number = 5 * 60 * 1000; // 5分钟缓存时间

  constructor(apiProvider: ApiProvider = 'frankfurter') {
      this.apiProvider = apiProvider;
      this.cache = new Map();
  }

  // 生成缓存键
  private getCacheKey(fromCurrency: string, toCurrency: string): string {
      return `${fromCurrency.toUpperCase()}_${toCurrency.toUpperCase()}`;
  }

  // 检查缓存是否有效
  private isValidCache(cacheEntry: CacheEntry | undefined): boolean {
      return !!cacheEntry && (Date.now() - cacheEntry.timestamp) < this.CACHE_DURATION;
  }

  // 获取缓存数据
  private getFromCache(fromCurrency: string, toCurrency: string): number | null {
      const cacheKey = this.getCacheKey(fromCurrency, toCurrency);
      const cacheEntry = this.cache.get(cacheKey);

      if (this.isValidCache(cacheEntry)) {
          return cacheEntry?.rate || 0;
      }

      // 清除过期缓存
      if (cacheEntry) {
          this.cache.delete(cacheKey);
      }

      return null;
  }

  // 保存到缓存
  private saveToCache(fromCurrency: string, toCurrency: string, rate: number): void {
      const cacheKey = this.getCacheKey(fromCurrency, toCurrency);
      this.cache.set(cacheKey, {
          rate: rate,
          timestamp: Date.now()
      });
  }

  // 获取汇率数据
  private async fetchExchangeRate(fromCurrency: string, toCurrency: string): Promise<number> {
      const currencies = [fromCurrency, toCurrency].map(c => c.toUpperCase());

      try {
          let rate: number;

          if (this.apiProvider === 'frankfurter') {
              const response = await fetch(`https://api.frankfurter.app/latest?from=${currencies[0]}&to=${currencies[1]}`);
              
              if (!response.ok) {
                  throw new Error(`HTTP错误: ${response.status}`);
              }

              const data: FrankfurterResponse = await response.json();
              rate = data.rates[currencies[1]];
          } else {
              const response = await fetch(`https://api.exchangerate-api.com/v4/latest/${currencies[0]}`);
              
              if (!response.ok) {
                  throw new Error(`HTTP错误: ${response.status}`);
              }

              const data: ExchangeRateResponse = await response.json();
              rate = data.rates[currencies[1]];
          }

          if (!rate) {
              throw new Error('无法获取汇率数据');
          }

          return rate;
      } catch (error) {
          console.error('获取汇率数据失败:', error);
          throw new Error(`获取汇率失败: ${error instanceof Error ? error.message : '未知错误'}`);
      }
  }

  async convert(amount: number, fromCurrency: string, toCurrency: string): Promise<number> {
      const currencies = [fromCurrency, toCurrency].map(c => c.toUpperCase());

      // 如果是相同货币，直接返回原金额
      if (currencies[0] === currencies[1]) {
          return parseFloat(amount.toFixed(2));
      }

      try {
          // 先检查缓存
          const cachedRate = this.getFromCache(currencies[0], currencies[1]);
          let rate: number;

          if (cachedRate !== null) {
              rate = cachedRate;
          } else {
              console.log('发起API请求');
              rate = await this.fetchExchangeRate(currencies[0], currencies[1]);
              
              // 保存到缓存
              this.saveToCache(currencies[0], currencies[1], rate);
          }

          return parseFloat((amount * rate).toFixed(2));
      } catch (error) {
          console.error('汇率转换错误:', error);
          throw new Error(`汇率转换失败: ${error instanceof Error ? error.message : '未知错误'}`);
      }
  }

  // 清空缓存
  clearCache(): void {
      this.cache.clear();
      console.log('缓存已清空');
  }

  // 获取缓存信息
  getCacheInfo(): CacheInfo {
      const now = Date.now();
      const cacheEntries: CacheInfoEntry[] = Array.from(this.cache.entries()).map(([key, value]) => {
          const age = Math.floor((now - value.timestamp) / 1000);
          const expiresIn = Math.max(0, this.CACHE_DURATION / 1000 - age);
          return {
              key,
              rate: value.rate,
              age: `${age}秒`,
              expiresIn: `${expiresIn}秒`
          };
      });

      return {
          size: this.cache.size,
          entries: cacheEntries
      };
  }

  // 获取当前API提供商
  getApiProvider(): ApiProvider {
      return this.apiProvider;
  }

  // 设置API提供商
  setApiProvider(provider: ApiProvider): void {
      this.apiProvider = provider;
  }

  // 获取缓存大小
  getCacheSize(): number {
      return this.cache.size;
  }
}

export default CurrencyConverter;
export type { ApiProvider, CacheInfo, CacheInfoEntry };